
const $request = require('../utils/request.js')
const config = require('../utils/config.js')

const hx = require("hbuilderx");



function generateCodeHandler(context) {
	console.log('自动续写启动')
	generateCode(context)
}

const generateCode = (context)=>{
	
	
	// 防抖提示提供器
	function DebouncedInlineProvider() {
	    this.lastAbortController = null;
	    this.delayTimer = null;
	    this.DEBOUNCE_DELAY = 500; // 1秒防抖延迟
		this.lastAiContent = ''
		this.isAcceptLine = false
		this.acceptLineStatus = false
	}
	
	// 判断是否应该触发提示的条件
	DebouncedInlineProvider.prototype.shouldTrigger = function(document, position) {
	    // 获取当前行和光标前的文本
	    const line = document.lineAt(position.line);
	    const textBeforeCursor = line.text.substring(0, position.character);
	    
	    return (
	        !isInsideStringOrComment(document, position) // 不在字符串/注释中
	    );
	};
	
	// 辅助函数：检查是否在字符串或注释中
	function isInsideStringOrComment(document, position) {

	    const lineText = document.lineAt(position.line).text;
	    const textBefore = lineText.substring(0, position.character);
	    
	    // 检查是否在字符串中
	    const stringRegex = /(["'`]).*\1/;
	    if (stringRegex.test(textBefore)) {
	        return true;
	    }
	    
	    // 检查是否在注释中
	    if (textBefore.includes('//') || textBefore.includes('/*')) {
	        return true;
	    }
	    
	    return false;
	}
	
	var suggestionCache = {};
	// 实际获取提示的方法
	DebouncedInlineProvider.prototype.fetchAISuggestions = function(document, position, token) {
		
	    return new Promise( async (resolve) => {
			if (token && token.aborted) {
				resolve([]);
				return;
			}
			// 缓存逻辑
			// var cacheKey = document.uri + ':' + position.line + ':' + position.character;
			// if (suggestionCache[cacheKey]) {
			//     resolve([suggestionCache[cacheKey]]);
			// }
			console.log('发送请求')
			let res = await $request.generateCode(document, position)
			resolve([res])
	    });
	};
	
	// 防抖处理的核心方法
	DebouncedInlineProvider.prototype.debouncedProvide = function(document, position,cancellationToken) {
	    var self = this;
		//检查是否开启自动代码提示
		if(!config.getData('codePrompt')){
			return Promise.resolve({ items: [] });
		}
		//检查是否在逐行操作
		if(self.isAcceptLine){
			if(self.lastAiContent){
				console.log('逐行操作不触发')
				return Promise.resolve({ items: [{
							insertText: self.lastAiContent,
							range: new hx.Range(position, position)
						}] })
			}else{
				self.isAcceptLine = false
				return Promise.resolve({ items: [] });
			}
		}
		
	    // 首先检查触发条件
		if (!self.shouldTrigger(document, position)) {
			console.log('不触发')
			return Promise.resolve({ items: [] });
		}
	    // 取消之前的请求
	    if (self.lastAbortController) {
	        self.lastAbortController.abort();
	        self.lastAbortController = null;
	    }
	    
	    // 清除之前的计时器
	    if (self.delayTimer) {
	        clearTimeout(self.delayTimer);
	    }
	    
	    // 创建新的AbortController
	    var controller = new AbortController();
	    self.lastAbortController = controller;
	    
	    return new Promise(function(resolve) {
	        self.delayTimer = setTimeout(async function() {
	            try {
	                var suggestions = await self.fetchAISuggestions(
	                    document, 
	                    position, 
	                    { aborted: controller.signal.aborted }
	                );
	                
	                // 转换为编辑器需要的格式
	                var items = suggestions.map(function(text) {
	                    return {
	                        insertText: text,
	                        range: new hx.Range(position, position)
	                    };
	                });
					if(suggestions[0]){
						hx.window.setStatusBarMessage('ucoder:接受行(Ctrl+↓)舍弃行(Ctrl+→)撤销行(Ctrl+↑)',0,'info');
					}
	                self.lastAiContent = suggestions[0]
	                resolve({ items: items });
	            } catch (err) {
	                if (err.name !== 'AbortError') {
	                    console.error("提示获取失败:", err);
	                }
					self.lastAiContent = ''
	                resolve({ items: [] });
	            }
	        }, self.DEBOUNCE_DELAY);
	    });
	};
	var provider = new DebouncedInlineProvider();
	function registerInlineCompletion() {
	    
	    var disposable = hx.languages.registerInlineCompletionItemProvider(
	        [{ pattern: '**' }],
	        {
	            provideInlineCompletionItems: function(document, position, context, token) {
	                return provider.debouncedProvide(document, position,token);
	            }
	        }
	    );
	    
	    return disposable;
	}
	
	var completionDisposable = registerInlineCompletion();
	context.subscriptions.push(completionDisposable);
	
	hx.commands.registerCommand('ucoder.acceptLine',async ()=>{
		if(!provider.lastAiContent)return
		provider.isAcceptLine = true
		let lines = provider.lastAiContent.split('\n')
		let setline = ''
		let isempty = true
		while(isempty){
			setline = lines.shift()
			setline = '\n'+setline
			if(setline.trim()!='')isempty=false
		}
		lines.length>0?provider.lastAiContent = '\n'+lines.join('\n'):provider.lastAiContent = ''
		insertCode(setline,provider.lastAiContent)
		})
	hx.commands.registerCommand('ucoder.abandonLine',async ()=>{
		if(!provider.lastAiContent)return
		provider.isAcceptLine = true
		let lines = provider.lastAiContent.split('\n')
		let setline = ''
		let isempty = true
		while(isempty){
			setline = lines.shift()
			if(setline.trim()!='')isempty=false
		}
		lines.length>0?provider.lastAiContent = '\n'+lines.join('\n'):provider.lastAiContent = ''
			triggerByFakeInput()
			console.log('舍弃行')
		})
	hx.commands.registerCommand('ucoder.revokeLine',async ()=>{
			let activeEditor = hx.window.getActiveTextEditor();
			activeEditor.then(function(editor) {
				let linePromise = editor.document.lineFromPosition(editor.selection.active);
				linePromise.then((line)=>{
					provider.isAcceptLine = true
					let lines = provider.lastAiContent.split('\n')
					let newlines = [line.text,...lines]
					provider.lastAiContent = '\n'+newlines.join('\n')
					
					provider.acceptLineStatus = true
					setTimeout(()=>{
						provider.acceptLineStatus = false
						triggerByFakeInput()
					},100)
					console.log('撤销行')
					
					setTimeout(()=>{
						hx.commands.executeCommand('editor.action.deleteLines')
					},10)
					setTimeout(()=>{
						hx.commands.executeCommand('cursorUp')
					},20)
					setTimeout(()=>{
						hx.commands.executeCommand('cursorLineEnd')
					},30)
					
					// console.log("Line info:", line.text, "开始位置：", line.start, "结束位置：", line.end);
					
				});
			});
		})
	
	async function insertCode(content,AiContent) {
		try {
			const activeTextEditor = await hx.window.getActiveTextEditor()
			if (!activeTextEditor) {
				console.warn('没有活动的文本编辑器');
				return;
			}
			activeTextEditor.edit((editBuilder => {
				provider.acceptLineStatus = true
				setTimeout(()=>{
					provider.acceptLineStatus = false
				},100)
				console.log('接受行')
				
				const selection = activeTextEditor.selection;
				editBuilder.replace(selection, content)
				setTimeout(()=>{
					hx.commands.executeCommand('cursorDown')
				},10)
				setTimeout(()=>{
					hx.commands.executeCommand('cursorLineEnd')
				},20)
			}));
			
		} catch (error) {
			provider.isAcceptLine = false
			console.error('插入代码失败:', error);
			hx.window.showErrorMessage('插入代码失败: ' + error.message);
		}
	
	}
	
	// 通过模拟输入触发代码提示
	async function triggerByFakeInput() {
		console.log('模拟输入')
		const activeTextEditor = await hx.window.getActiveTextEditor()
		if (!activeTextEditor) {
			console.warn('没有活动的文本编辑器');
			return;
		}
		activeTextEditor.edit((editBuilder => {
			provider.acceptLineStatus = true
			setTimeout(()=>{
				provider.acceptLineStatus = false
			},100)
			
			const selection = activeTextEditor.selection;
			editBuilder.replace(selection, ';')
			setTimeout(()=>{
				hx.commands.executeCommand('cursorLineEnd')
			},10)
			setTimeout(()=>{
				hx.commands.executeCommand('deleteLeft')
			},20)
			
		}));
	}
	
	let onDidChangeTextDocumentEventDispose = hx.workspace.onDidChangeTextDocument(function(event){
			if(!provider.acceptLineStatus&&provider.isAcceptLine){
				provider.isAcceptLine=false
				provider.lastAiContent = ''
				hx.window.clearStatusBarMessage();
				console.log('清空逐行操作')
			}
	    });
		
	context.subscriptions.push(onDidChangeTextDocumentEventDispose);
	
}

module.exports = {
	generateCodeHandler
}